package cloud.shyidong.tenant.controller;

import cloud.shyidong.core.Result;
import cloud.shyidong.core.controller.AbstractController;
import cloud.shyidong.core.exception.BusinessException;
import cloud.shyidong.core.exception.WeixinException;
import cloud.shyidong.core.request.LongIdRequest;
import cloud.shyidong.core.util.*;
import cloud.shyidong.core.wxpay.WxpayConfig;
import cloud.shyidong.tenant.dao.TenantOrderDao;
import cloud.shyidong.tenant.entity.TenantOrderEntity;
import cloud.shyidong.tenant.request.TenantOrderInsertRequest;
import cloud.shyidong.tenant.request.TenantOrderPageRequest;
import cloud.shyidong.tenant.request.TenantOrderPrepayRequest;
import cloud.shyidong.tenant.request.TenantOrderUpdateRequest;
import cloud.shyidong.tenant.service.impl.OrderService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.java.core.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.PrivateKey;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * <p>
 * 租户订单控制器
 * </p>
 *
 * @author syd
 * @since 2023-09-19 11:53:35
 */
@RestController
@RequestMapping("/tenant-order")
@Slf4j
public class OrderController extends AbstractController<OrderService, TenantOrderDao, TenantOrderEntity, LongIdRequest, TenantOrderInsertRequest, TenantOrderUpdateRequest, TenantOrderPageRequest> {
    
    private WxpayConfig wxpayConfig;
    
    @Autowired
    public void setWxpayConfig(WxpayConfig wxpayConfig) {
        this.wxpayConfig = wxpayConfig;
    }
    
    @GetMapping("/before-prepay")
    public Result beforePrepay(LongIdRequest longIdRequest) {
        if (log.isDebugEnabled()) {
            log.debug("before-prepay param >>> {}", JSON.toJSONString(longIdRequest));
        }
        return getService().beforePrepay(longIdRequest);
    }
    
    /**
     * 预支付接口
     *
     * @param tenantOrderPrepayRequest
     * @param httpServletResponse
     */
    @GetMapping("/prepay")
    public void prepay(TenantOrderPrepayRequest tenantOrderPrepayRequest, HttpServletResponse httpServletResponse) throws Exception {
        
        if (log.isDebugEnabled()) {
            log.debug("prepay param >>> {}", JSON.toJSONString(tenantOrderPrepayRequest));
        }
        
        if (ObjectUtils.isNull(tenantOrderPrepayRequest) || StringUtils.isEmpty(tenantOrderPrepayRequest.getCodeUrl())) {
            throw BusinessException.from("缺少二维码URL");
        }
        
        QRCodeUtil.encode(tenantOrderPrepayRequest.getCodeUrl(), httpServletResponse);
        
    }
    
    /**
     * 支付通知请求
     *
     * @param httpServletRequest
     * @param httpServletResponse
     */
    @PostMapping("/notify")
    public String notify(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        String body = WebUtils.getRequestBody(httpServletRequest);
        log.info("body >>> {}", body);
        try {
            PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(wxpayConfig.getPrivateKeyPath());
            PrivateKeySigner privateKeySigner = new PrivateKeySigner(wxpayConfig.getMerchantSerialNumber(), privateKey);
            WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(wxpayConfig.getMchId(), privateKeySigner);
            CertificatesManager certificatesManager = CertificatesManager.getInstance();
            certificatesManager.putMerchant(wxpayConfig.getMchId(), wechatPay2Credentials, wxpayConfig.getApiV3Key().trim().getBytes());
            Verifier verifier = certificatesManager.getVerifier(wxpayConfig.getMchId());
            WeixinUtils.verifySignature(verifier, body, httpServletRequest);
            String plainText = WeixinUtils.decryptBody(wxpayConfig.getApiV3Key(), body);
            getService().updatePaymentByOrderNo(plainText);
        } catch (WeixinException e) {
            httpServletResponse.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            return JSONObject.toJSONString(e);
        } catch (Exception e) {
            httpServletResponse.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            return JSONObject.toJSONString(WeixinException.from("FAIL", "支付回调失败"));
        }
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("code", "SUCCESS");
        map.put("message", "成功");
        return new JSONObject(map).toJSONString();
    }
    
}

